<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>11_ES12-WeakRefs弱引用</title>
  <!-- 
  在 JavaScript 的 ES12（ECMAScript 2021）中，引入了  `WeakRef` （弱引用）这一新特性。 `WeakRef`  提供了一种机制，可以创建对对象的弱引用，这意味着这些对象可以在没有其他强引用的情况下被垃圾回收。
  一、定义
  `WeakRef`  是一个内置的 JavaScript 对象，它允许你创建对某个对象的弱引用。与强引用不同，弱引用不会阻止垃圾回收器回收对象。这在某些情况下非常有用，例如缓存机制或复杂数据结构的管理。

  二、构造函数
   1. 语法
  const weakRef = new WeakRef(target);
  - target：要创建弱引用的对象。

  三、使用过程
   1. 创建弱引用

  使用  `WeakRef`  构造函数创建一个对对象的弱引用。

   2. 获取对象

  通过  `deref()`  方法可以获取弱引用指向的对象。如果该对象已经被垃圾回收，则  `deref()`  返回  `undefined` 。

   3. 示例

  以下是一个简单的示例，展示了如何使用  `WeakRef` ：
  // 创建一个对象
  let obj = { name: '小明' };

  // 创建一个对该对象的弱引用
  const weakRef = new WeakRef(obj);

  // 获取对象
  let derefObj = weakRef.deref();
  console.log(derefObj); // 输出: { name: '小明' }

  // 删除对对象的强引用
  obj = null;

  // 触发垃圾回收（注意：垃圾回收是非确定性的，可能不会立即发生）
  setTimeout(() => {
      derefObj = weakRef.deref();
      console.log(derefObj); // 输出: undefined（如果对象被回收）
  }, 1000);
  在这个示例中，创建了一个对象  `obj` ，然后通过  `WeakRef`  创建了一个对它的弱引用。在删除对  `obj`  的强引用后，如果垃圾回收器回收了该对象，调用  `deref()`  将返回  `undefined` 。

  四、注意事项
  1. 非确定性：垃圾回收是非确定性的，无法控制何时发生，因此无法保证弱引用的对象何时被回收。
  2. 用途：弱引用适用于缓存、事件监听等场景，可以避免内存泄漏，同时不阻止对象被垃圾回收。
  3. 性能考虑：虽然弱引用提供了更灵活的内存管理，但在高频率创建和销毁对象的情况下，使用不当可能会影响性能。

  五、总结
  - 功能： `WeakRef`  提供了一种创建弱引用的机制，使得对象可以在没有强引用的情况下被垃圾回收。
  - 方法：使用  `deref()`  方法获取弱引用指向的对象，如果对象已被回收，则返回  `undefined` 。
  - 适用场景：适合用于缓存、事件处理等需要灵活管理内存的场景。
  -->
</head>
<body>

  <script>
    let info = {
      name: 'WeakRefs弱引用',
      age: 18
    }
    let obj = new WeakRef(info)
    let obj2 = new WeakRef(info)

    const finalizationRegistry = new FinalizationRegistry((value) => {
      console.log(value, '被垃圾回收了')
    })

    finalizationRegistry.register(info, 'info')

    setTimeout(() => {
      info = null
    }, 2000)

    setTimeout(() => {
      console.log(obj.deref().name, obj.deref().age)
    }, 5000)

    // WeakRef 对象的 deref 方法返回一个对原始对象的弱引用，如果原始对象已被垃圾回收，则返回 undefined。
    // setTimeout(() => {
    //   console.log(obj.deref())
    // }, 5000)

    
  </script>
  
</body>
</html>